#include "Parser.h"

/* Parser */
void initParser(char ptr filename, int createCode)
{
    initScanner(filename);
    initCodeGenerator();
    generateCode = createCode;
}

void primeval()
{
    mark("Primeval", 0);
    if(curKey-> sym neq ENDF)
    {
        get();
        while(curKey-> sym equ INVOL)
        {
            get();
            involvement();
        }
        sequences();
        statementSequence();
    }
    printf("Primeval done!");
}

void sequenceList()
{
    if(curKey-> sym equ IDENT)
    {
        get();
        while(curKey-> sym equ PERIOD)
        {
            get();
            sequenceList();
        }
    }
    else
    {
        mark("Identifier expected", 1);
    }
}

void statementSequence()
{
    while (curKey-> sym neq ENDF)
    {
        while(curKey-> sym neq IDENT and
          curKey-> sym neq TYP and curKey-> sym neq STRUCT and
          curKey-> sym neq FUNC and curKey-> sym neq CONST and
          curKey-> sym neq TYPEDEF and curKey-> sym neq ENDF)
        {
            get();
            mark("statement expected", 1);
        }

        if(curKey-> sym equ FUNC)
        {
            procedureDeclaration();
        }
        else
        {
            declaration();
        }
    }
    mark("AWESOME JOB, MAN!!!", 0);
}

void statement()
{
    if(curKey-> sym equ TYP or curKey-> sym equ STRUCT or curKey-> sym equ CONST)
    {
        declaration();
    }
    elif(curKey-> sym equ WHILE)
    {
        whileStatement();
    }
    elif(curKey-> sym equ IF)
    {
        ifStatement();
    }
    elif(curKey-> sym equ IDENT)
    {
        string_t name = getCurValue();
        get();
        if(curKey-> sym equ LPAREN)
        {
            object_t object = searchProcedure(name);
            if(object equ NULL)
            {
                info("Procedure not found");
                object = newObject;
                object-> name = name;
                object-> oClass = CLASSFUNC;
                object-> type = unknType;
                object-> offset = 0;
                object-> params = newSymTab;
                initSubSymTab(object-> params);
                addObj(bottom, object);
            }
            item_t item = newItem;
            item-> mode = MODEREG;
            item-> type = object-> type;

            if(strcmp("printInt", name) neq 0 and
               strcmp("readInt", name) neq 0)
            {
                pushUsedRegisters();
            }
            actualParameters(object);
            if(strcmp("printInt", name) neq 0 and
               strcmp("readInt", name) neq 0)
            {
                if(object-> offset neq 0 and isBSR(object-> offset) equ 0)
                {
                    sJump(object-> offset - programCounter);
                }
                else
                {
                    object-> offset = sJump(object-> offset);
                }
                popUsedRegisters();
            }
            item-> reg = getRegister();
            put(ADD, item-> reg, 0, RETREG);
        }
        elif(curKey-> sym equ BECOME)
        {
            object_t o = search(name);
            if(o equ NULL)
            {
                mark("Unknown identifier", 1);
                return;
            }

            item_t left = getVarItem(o);
            get();
            item_t right = expression();
            assignBinaryOperator(left, right);
        }
        elif(curKey-> sym equ ARROW or
             curKey-> sym equ LBRAK)
        {
            object_t o = search(name);
            if(o equ NULL)
            {
                mark("Unknown identifier", 1);
                return;
            }

            item_t left = getVarItem(o);
            selector(left);
            if(curKey-> sym equ BECOME)
            {
                get();
                assignBinaryOperator(left, expression());
            }
            else
            {
                mark("Assignment expected", 1);
            }
        }
        elif(curKey-> sym equ IDENT)
        {
            object_t o = search(name);
            if(o equ NULL)
            {
                mark("Unknown identifier", 1);
                return;
            }

            object_t object = identDeclaration(o-> type, CLASSVAR);
            if(curKey-> sym equ BECOME)
            {
                get();
                assignBinaryOperator(getVarItem(object), expression());
            }
        }
        else
        {
            mark("Identifier, (, ->, [, =, expected", 1);
        }

        if(curKey-> sym equ COLON)
        {
            get();
        }
        else
        {
            mark("Semicolon expected", 1);
        }
    }
    elif (curKey-> sym equ RETURN)
    {   /*
        get();
        if(curKey-> sym equ COLON)
        {
            get();
        }
        else
        {
            expression();
            if(curKey-> sym equ COLON)
            {
                get();
            }
            else
            {
                mark("Semicolon expected at return Statement", 1);
            }
        }
        */
        item_t item;

        get();
        if ((curKey-> sym equ PLUS) or (curKey-> sym equ MINUS) or
            (curKey-> sym equ IDENT) or (curKey-> sym equ NUMBER) or
            (curKey-> sym equ LPAREN) or (curKey-> sym equ NOT) or (curKey-> sym equ STRING))
        {
            item = expression();
            if (item->type neq procedureContext->type)
            {
                mark("return type mismatch", 1);
            }
            if (item->type equ boolType)
            {
                unloadBool(item);
            }
            load(item);
            put(ADD, RETREG, 0, item->reg);
            freeReg(item->reg);
            if(curKey-> sym equ COLON)
            {
                get();
            }
            else
            {
                mark("Semicolon expected at return Statement", 1);
            }
        }
        returnFJumpAddress = fJumpChain(returnFJumpAddress);
    }
    else
    {
        mark("Statement expected", 1);
    }
    mark("Statement successfully parsed", 0);
}

void procedureDeclaration()
{
    if(curKey-> sym equ FUNC)
    {
        get();

        item_t item = newItem;
        item-> type = type();
        if(curKey-> sym equ IDENT)
        {
            string_t name = getCurValue();
            if(strcmp(name, "main") equ 0)
            {
                putSpecific(1, BR, 0, 0, (programCounter - 1));
            }

            object_t o = searchProcedure(name);
            if(o neq NULL)
            {
                if(o-> type neq unknType and o-> type neq item-> type)
                {
                    mark("return type mismatch in procedure", 1);
                }
                fixLink(o-> offset);
            }
            else
            {
                o = newObject;
                o-> name = name;
                o-> oClass = CLASSFUNC;
                o-> params = newSymTab;
                initSubSymTab(o-> params);
                newObj(o);
            }

            get();
            o-> type = item-> type;
            o-> offset = programCounter;

            if(curKey-> sym equ LPAREN)
            {
                get();

                if(curKey-> sym equ TYP or curKey-> sym equ CONST or
                   curKey-> sym equ STRUCT or curKey-> sym equ IDENT)
                {
                    formalParameters(o, o-> params-> head);
                    setParamAddresses(o);
                }
                if(curKey-> sym equ RPAREN)
                {
                    get();
                    returnFJumpAddress = 0;
                    procedureContext = o;
                    if(curKey-> sym equ LBRACE)
                    {
                        prologue();
                        body(o);
                    }
                    else
                    {
                        mark("Semicolon or left brace expected", 1);
                    }
                    fixLink(returnFJumpAddress);
                    epilogue(o-> params-> length * 4);

                }
                else
                {
                    mark("Right parentity expected", 1);
                }
            }
            else
            {
                mark("Left parentity expected", 1);
            }
        }
        else
        {
            mark("Identifier expected", 1);
        }
    }
    else
    {
        mark("void expected", 1);
    }
    mark("Procedure successfully parsed", 0);
}

void body()
{
    if(curKey-> sym equ LBRACE)
    {
        get();
        newStage();
        while(curKey-> sym equ IDENT or curKey-> sym equ IF or curKey-> sym equ WHILE or
              curKey-> sym equ TYP or curKey-> sym equ STRUCT or curKey-> sym equ CONST or
              curKey-> sym equ RETURN)
        {
            statement();
        }
        if(curKey-> sym equ RBRACE)
        {
            get();
        }
        else
        {
            mark("Right brace expected(body)", 1);
        }
        pop();
    }
    else
    {
        mark("Left brace expected", 1);
    }
    mark("Body successfully parsed", 0);
}

void formalParameters(object_t procedure, object_t formalParam)
{
    type_t typ = type();
    if(curKey-> sym equ IDENT)
    {
        string_t name = getCurValue();
        if(formalParam neq NULL)
        {
            if(typ neq formalParam-> type)
            {
                error("type mismatch in procedure declaration");
            }
            if(getByName(procedure-> params, name) neq NULL)
            {
                error("duplicate parameter name in procedure declaration");
            }
            formalParam-> name = name;
        }
        else
        {
            object_t param = newObject;
            param-> type = typ;
            param-> name = name;
            addObjectToParams(procedure, param);
        }
        get();
    }
    else
    {
        mark("Identifier expected", 1);
    }
    if(curKey-> sym equ COMMA)
    {
        get();
        if(formalParam neq NULL)
        {
            formalParameters(procedure, formalParam-> next);
        }
        else
        {
            formalParameters(procedure, NULL);
        }
    }
    mark("Formal parameters successfully parsed", 0);
}

void declaration()
{
    if(curKey-> sym equ STRUCT)
    {
        get();
        if(curKey-> sym equ IDENT)
        {
            string_t typeOrName = getCurValue();
            get();
            if(curKey-> sym equ PTR)
            {
                get();
                object_t typeObject = search(typeOrName);
                if(typeObject neq NULL)
                {
                    type_t curType = typeObject-> type;
                    while(curKey-> sym equ PTR)
                    {
                        get();
                        type_t tmp = newType;
                        tmp-> form = FORMARRAY;
                        tmp-> size = curType-> size;
                        tmp-> base = curType;
                        curType = tmp;
                    }
                    if(curKey-> sym equ IDENT)
                    {
                        object_t o = identDeclaration(curType, CLASSVAR);
                        if(curKey-> sym equ BECOME)
                        {
                            item_t left = getVarItem(o);
                            get();
                            assignBinaryOperator(left, expression());
                        }
                    }
                    else
                    {
                        mark("Identifier expected", 1);
                    }
                }
                else
                {
                    mark("Unknown identifier", 1);
                }
            }
            elif(curKey-> sym equ LBRACE)
            {
                get();
                type_t curType = newType;
                curType-> form = FORMSTRUCT;
                curType-> fields = newSymTab;
                initSubSymTab(curType-> fields);

                object_t o = newObject;
                o-> oClass = CLASSTYPE;
                o-> name = typeOrName;
                o-> type = curType;

                while(curKey-> sym equ TYP or curKey-> sym equ STRUCT or
                      curKey-> sym equ IDENT)
                {
                    fieldDeclaration(curType-> fields);
                }

                o-> type-> size = calcSize(curType-> fields);
                addObjectToMonster(o);
                if(curKey-> sym equ RBRACE)
                {
                    get();
                }
                else
                {
                    mark("Right brace expected (struct type)", 1);
                }
            }
            else
            {
                mark("Pointer or Identifier expected", 1);
            }
        }
        else
        {
            mark("Identifier expected", 1);
        }
    }
    elif(curKey-> sym equ TYPEDEF)
    {
        get();
        typeDeclaration();
    }
    else
    {
        if(curKey-> sym equ CONST)
        {
            get();
        }
        type_t curType = type();
        if(curType equ NULL or curType equ voidType)
        {
            mark("Unknown Type", 1);
        }
        object_t o = identDeclaration(curType, CLASSVAR);
        if(curKey-> sym equ BECOME)
        {
            item_t left = getVarItem(o);
            get();
            item_t right = expression();
            printItem(right);
            assignBinaryOperator(left, right);
        }
    }
    if(curKey-> sym equ COLON)
    {
        get();
    }
    else
    {
        mark("Semicolon expected", 1);
    }
    mark("Declaration successfully parsed", 0);
}

void typeDeclaration()
{
    type_t curType = type();
    identDeclaration(curType, CLASSTYPE);
}

void fieldDeclaration(symTab_t symTab)
{
    type_t curType = type();
    identListFields(curType, symTab);
    if(curKey-> sym equ COLON)
    {
        get();
    }
    else
    {
        mark("Semicolon expected", 1);
    }
    mark("FieldType successfully parsed", 0);
}

type_t type()
{
    type_t type = NULL;
    if(curKey-> sym equ TYP)
    {
        string_t val = getCurValue();
        if(strcmp(val, "int") equ 0)
        {
            type = intType;
        }
        elif(strcmp(val, "bool") equ 0)
        {
            type = boolType;
        }
        elif(strcmp(val, "char") equ 0)
        {
            type = charType;
        }
        elif(strcmp(val, "void") equ 0)
        {
            type = voidType;
        }
        else
        {
            mark("This kind of basic type is unknown", 1);
            return NULL;
        }
        get();
    }
    elif(curKey-> sym equ STRUCT)
    {
        get();
        type = structType();
    }
    elif(curKey-> sym equ IDENT)
    {
        object_t o = search(getCurValue());
        if(o neq NULL)
        {
            type = o-> type;
        }
        else
        {
            mark("Unknown identifier", 1);
        }
        get();
    }
    else
    {
        mark("Type or struct expected", 1);
    }
    while(curKey-> sym equ PTR)
    {
        type_t tmp = newType;
        tmp-> form = FORMARRAY;
        tmp-> size = type-> size;
        tmp-> base = type;
        type = tmp;
        get();
    }
    mark("Type successfully parsed", 0);

    return type;
}

type_t structType()
{
    type_t type = NULL;
    if(curKey-> sym equ IDENT)
    {
        object_t o = search(getCurValue());
        if(o neq NULL)
        {
            type = o-> type;
        }
        else
        {
            mark("Unknown identifier: ", 1);
        }
        get();
        if(curKey-> sym equ PTR)
        {
            get();
        }
        else
        {
            mark("Pointer expected", 1);
        }
    }
    else
    {
        mark("Identifier expected", 1);
    }
    return type;
}

object_t identDeclaration(type_t type, int class)
{
    object_t o = newObject;
    o-> type = type;
    o-> oClass = class;
    o-> name = getCurValue();
    addObjectToMonster(o);
    get();

    mark("Identifier declaration successfully", 0);
    return o;
}

void identListFields(type_t type, symTab_t symTab)
{
    object_t o = newObject;
    o-> type = type;
    o-> oClass = CLASSVAR;
    o-> scope = SCOPEFIELD;
    if(curKey-> sym equ IDENT)
    {
        o-> name = getCurValue();
        addObj(symTab, o);
        get();
        if(curKey-> sym equ COMMA)
        {
            get();
            identListFields(type, symTab);
        }
    }
    else
    {
        mark("Identifier expected identlist", 1);
    }
    mark("Identlist successfully parsed", 0);
}


void identList()
{
    if(curKey-> sym equ IDENT)
    {
        object_t o = search(getCurValue());
        if(o equ NULL)
        {
            mark("Unknown Symbol", 1);
        }
        get();
        if(curKey-> sym equ COMMA)
        {
            get();
            identList();
        }
    }
    else
    {
        mark("Identifier expected identlist", 1);
    }
    mark("Identlist successfully parsed", 0);
}

/*expression = simpleExpression [( "equ" | "neq" | "<" | ">" | "<=" | ">=") simpleExpression].*/
item_t expression()
{
    item_t left = simpleExpression();

    while(curKey-> sym equ EQL or curKey-> sym equ NEQ or curKey-> sym equ LSS or
       curKey-> sym equ GRT or curKey-> sym equ LEQ or curKey-> sym equ GEQ or
       curKey-> sym equ NOT)
    {

        int op = UNKN;
        // has to be switch cased because of different symbols for codegenerator and scanner
        if(curKey-> sym equ EQL)
        {
            op = BEQ;
        }
        elif(curKey-> sym equ NEQ)
        {
            op = BNE;
        }
        elif(curKey-> sym equ LSS)
        {
            op = BLT;
        }
        elif(curKey-> sym equ GRT)
        {
            op = BGT;
        }
        elif(curKey-> sym equ LEQ)
        {
            op = BLE;
        }
        elif(curKey-> sym equ GEQ)
        {
            op = BGE;
        }

        get();

        item_t right = simpleExpression();
        expressionOperator(left, right, op);
    }
    mark("Expression successfully parsed", 0);
    return left;
}


item_t simpleExpression()
{
    if(curKey-> sym equ PLUS or curKey-> sym equ MINUS)
    {
        get();
    }
    item_t left = term();

    while(curKey-> sym equ PLUS or curKey-> sym equ MINUS or curKey-> sym equ OR)
    {
        int op = curKey-> sym;
        get();
        if(op equ OR)
        {
            simpleExpressionOR(left);
        }
        item_t right = term();
        arithBinaryOperator(op, left, right);
    }
    mark("Simple Expression successfully parsed", 0);
    return left;
}

item_t term()
{
    item_t left = factor();

    while(curKey-> sym equ MOD or curKey-> sym equ TIMES or curKey-> sym equ DIV or curKey-> sym equ AND)
    {
        int op = curKey-> sym;
        get();
        if(op equ AND)
        {
            simpleExpressionAND(left);
        }
        item_t right = factor();
        arithBinaryOperator(op, left, right);
    }
    mark("Term successfully Parsed", 0);
    return left;
}

item_t factor()
{
    item_t item = NULL;
    int hasNot = 0;

    if(curKey-> sym equ NOT)
    {
        get();
        hasNot = 1;
    }

    if(curKey-> sym equ IDENT)
    {
        string_t name = getCurValue();
        get();

        if(curKey-> sym equ LPAREN)
        {
            object_t object = searchProcedure(name);
            if(object equ NULL)
            {
                info("Procedure not found");
                object = newObject;
                object-> name = name;
                object-> oClass = CLASSFUNC;
                object-> type = unknType;
                object-> offset = 0;
                object-> params = newSymTab;
                initSubSymTab(object-> params);
                addObj(bottom, object);
            }
            item = newItem;
            item-> mode = MODEREG;
            item-> type = object-> type;

            pushUsedRegisters();
            actualParameters(object);
            if(object-> offset neq 0 and isBSR(object-> offset) equ 0)
            {
                sJump(object-> offset - programCounter);
            }
            else
            {
                object-> offset = sJump(object-> offset);
            }
            popUsedRegisters();
            item-> reg = getRegister();
            put(ADD, item-> reg, 0, RETREG);
        }
        else
        {
            object_t object = getByName(procedureContext-> params, name);
            if(object equ NULL)
            {
                object = search(name);
            }
            if(object neq NULL)
            {
                item = getVarItem(object);
            }
            else
            {
                mark("Identifier unknown!", 1);
            }
        }
        selector(item);
    }
    elif(curKey-> sym equ NUMBER)
    {
        string_t sValue = getCurValue();
        int value = atoi(sValue);
        item = getConstItem(value);
        get();
    }
    elif(curKey-> sym equ BOOL)
    {
        string_t sValue = getCurValue();
        item = getConstBoolItem(sValue);
        get();
    }
    elif(curKey-> sym equ CHAR)
    {
        get();
    }
    elif(curKey-> sym equ LPAREN)
    {
        get();
        item = expression();
        if(curKey-> sym equ RPAREN)
        {
            get();
        }
        else
        {
            mark("Right parentity expected", 1);
        }
    }
    elif(curKey-> sym equ STRING)
    {
        //TODO: saveString(item, String);
        //SIEHE ARITHMETIC EXPRESSIONS L2 27MIN
        get();
    }
    elif(curKey-> sym equ STRUCT)
    {
        get();
        structType();
        while(curKey-> sym equ PTR)
        {
            get();
        }
    }
    elif(curKey-> sym equ TYP)
    {
        get();
        while(curKey-> sym equ PTR)
        {
            get();
        }
    }
    elif(curKey-> sym equ NEW)
    {
        get();
        type_t t = type();
        t-> size = calcSize(t-> fields);
        if(curKey-> sym equ LBRAK)
        {
            get();
            item = mallocItem(t, expression());
            if(curKey-> sym equ RBRAK)
            {
                get();
            }
            else
            {
                mark("Right bracket expected (new call)", 1);
            }
        }
        else
        {
            item = mallocItem(t, getConstItem(1));
        }
    }
    else
    {
        mark("Factor expected", 1);
    }

    if(hasNot equ 1)
    {
        factorOperator(item);
    }

    mark("Factor successfully Parsed", 0);
    return item;
}


void selector(item_t item)
{
    while(curKey-> sym equ LBRAK or curKey-> sym equ ARROW)
    {
        if(curKey-> sym equ ARROW)
        {
            get();
            if(curKey-> sym neq IDENT)
            {
                mark("Identifier expected(Selector)", 1);
            }
            else
            {
                if(item-> type-> form neq FORMSTRUCT)
                {
                    mark("You can not use select -> for this type", 1);
                }
                else
                {
                    object_t found = getByName(item-> type-> fields, getCurValue());
                    if(found equ NULL)
                    {
                        mark("Unknown Field", 1);
                    }
                    else
                    {
                        field(found, item);
                    }
                }
                get();
            }
        }
        elif(curKey-> sym equ LBRAK)
        {
            get();
            if(item-> type-> form neq FORMARRAY)
            {
                mark("You can not use selector [] for this kind of type", 1);
            }
            else
            {
                item_t indexItem = expression();
                indexer(indexItem, item);
            }

            if(curKey-> sym neq RBRAK)
            {
                mark("Left bracket expected", 1);
            }
            else
            {
                get();
            }
        }
    }
    mark("Selector successfully parsed", 0);
}

void ifStatement()
{
    if(curKey-> sym equ IF)
    {
        get();
        if(curKey-> sym equ LPAREN)
        {
            get();
            item_t item = expression();
            //int reg = item->reg;      // these two statements will fuck everything up...
            if(item-> type equ boolType)
            {
                loadBool(item);
                //item->reg = reg;
                conditionalJump(item);
                fixLink(item-> tru);
            }

            if(curKey-> sym equ RPAREN)
            {
                get();
                body();
                while(curKey-> sym equ ELIF)
                {
                    get();
                    if(curKey-> sym equ LPAREN)
                    {
                        get();
                        expression(NULL);
                        if(curKey-> sym equ RPAREN)
                        {
                            get();
                            body();
                        }
                        else
                        {
                            mark("Right parentity expected", 1);
                        }
                    }
                    else
                    {
                        mark("Left parentity expected", 1);
                    }
                }
                if(curKey-> sym equ ELSE)
                {
                    get();
                    fJumpAddress = forwardJump();
                    fixLink(item-> fls);
                    body();
                    fixUp(fJumpAddress);
                }
                else
                {
                    fixLink(item-> fls);
                }
            }
            else
            {
                mark("Right parentity expected", 1);
            }
        }
        else
        {
            mark("Left parentity expected", 1);
        }
    }
    else
    {
        mark("if expected", 1);
    }
    mark("If statement successfully parsed", 0);
}


void whileStatement()
{
    if(curKey-> sym equ WHILE)
    {
        get();
        if(curKey-> sym equ LPAREN)
        {
            get();
            bJumpAddress = programCounter;
            item_t item = expression();
            int reg = item->reg;    // aka doSomething ...

            if(item neq NULL and item-> type equ boolType)
            {
                loadBool(item);
                item->reg = reg;
                conditionalJump(item);
                fixLink(item-> tru);
            }
            else
            {
                mark("Boolean Expression expected", 1);
            }

            if(curKey-> sym equ RPAREN)
            {
                get();
                body();
                bJump(bJumpAddress);
                fixLink(item-> fls);
            }
            else
            {
                mark("Right parentity expected", 1);
            }
        }
        else
        {
            mark("Left parentity expected", 1);
        }
    }
    else
    {
        mark("while expected", 1);
    }
    mark("While statement successfully parsed", 0);
}

void actualParameters(object_t o)
{
    if(curKey-> sym equ LPAREN)
    {
        get();
        if(curKey-> sym equ RPAREN)
        {
            get();
        }
        else
        {
            int paramNum = 1;
            object_t param = o-> params-> head;
            param = actualParameter(o, param, paramNum);
            while(curKey-> sym equ COMMA)
            {
                get();
                paramNum = paramNum + 1;
                param = actualParameter(o, param, paramNum);
            }
            if(curKey-> sym neq RPAREN)
            {
                mark("Right parentity expected", 1);
            }
            else
            {
                get();
            }
        }
    }
    mark("ActualParameters successfully parsed", 0);
}

object_t actualParameter(object_t object, object_t formalParam, int paramNum)
{
    item_t item = expression();
    if(formalParam neq NULL)
    {
        if(item-> type neq formalParam-> type)
        {
            error("type mismatch in procedure call");
        }

        if(strcmp("printInt", object-> name) neq 0 and
           strcmp("readInt", object-> name) neq 0)
        {
            pushParameter(item);
        }
        else
        {
            int reg = item-> reg;
            load(item);
            if(strcmp("printInt", object-> name) equ 0)
            {
                put(PRINTI, item-> reg, 0, 0);
            }
            elif(strcmp("readInt", object-> name) equ 0)
            {
                put(READI, item-> reg, 0, 0);
                put(STW, item-> reg, reg, item-> offset);
            }
        }
        return formalParam-> next;
    }
    formalParam = newObject;
    formalParam-> type = item-> type;
    string_t name = malloc(10);
    sprintf(name, "param%d", paramNum);
    formalParam-> name = name;
    addObjectToParams(object, formalParam);
    pushParameter(item);

    return NULL;
}

void sequenceSelector()
{
    while(curKey-> sym equ PERIOD)
    {
        get();
        if(curKey-> sym equ IDENT)
        {
            get();
        }
        else
        {
            mark("Identifier expected", 1);

        }
    }
}

void sequences()
{
    if(curKey-> sym equ SEQ)
    {
        get();
        sequenceList();
        if(curKey-> sym equ COLON)
        {
            get();
        }
        else
        {
            mark("Semicolon expected", 1);
        }
    }
    else
    {
        mark("sequence expected", 1);
    }
    mark("Sequence successfully parsed", 0);
}

void involvement()
{
    if(curKey-> sym equ IDENT)
    {
        get();
        sequenceSelector();
        if(curKey-> sym equ COLON)
        {
            get();
        }
        else
        {
            mark("semicolon expected", 1);
        }
    }
    else
    {
        mark("identifier expected", 1);
    }
    mark("Involve successfully parsed", 0);
}

void clearParser()
{
    clearScanner();
}
